package main

import (
	"fmt"
	"reflect"
)

/*
1、基本应用
(1)结构体序列化和反序列时，用到的tag标签
(2)使用一个适配器函数用作统一处理接口
bridge:=func(call interface{},args ...interface{}){}
2、介绍
(1)反射可以在运行时动态获取变量的各种信息，比如变量的类型(type)，类别(kind)
(2)如果是结构体变量，还可以获取到结构体本身的信息(包括结构体的字段、方法)
(3)通过反射，可以修改变量的值，可以调用关联的方法
(4)使用反射，需要import "reflect"
reflect包实现了运行时反射，允许程序操作任意类型的对象。
典型用法是用静态类型interface{}保存一个值，通过调用TypeOf获取其动态类型信息，该函数返回一个Type类型值。
调用ValueOf函数返回一个Value类型值，该值代表运行时的数据。
Zero接受一个Type类型参数并返回一个代表该类型零值的Value类型值。
(5)Go 语言提供了一种机制在运行时更新变量和检查它们的值、调用它们的方法，但是在编译时并不知道这些变量的具体类型，这称为反射机制。
3、反射的相关函数和转换
(1)reflect.TypeOf(变量名)，获取变量的类型，返回reflect.Type类型
(2)reflect.ValueOf(变量名)，获取变量的值，返回reflect.Value类型，是一个结构体类型。通过reflect.Value，可以获取到关于该变量的很多信息
(3)变量、interface{}和reflect.Value是可以相互转换的，这点在实际开发中，会经常使用到
*/
type Stu struct {
	Name string
	Age  int
}

//3(3)
//专用于做反射
func test(b interface{}) {
	//1如何将interface{}转成reflect.Value
	rVal := reflect.ValueOf(b)
	//2如何将reflect.Value -> interface{}
	iVal := rVal.Interface()
	//3如何将interface{}转成原来的变量类型，使用类型断言
	v := iVal.(Stu)
	fmt.Println(v)
}
func main() {
	var stu Stu
	test(stu)
}
